lowing the compare, we note that if they are not equal (i.e. OK button not hit) then it goes off somewhere. The next instruction must be the one that executes after the user hits the OK button. So set your breakpoint at the line that reads CLR.W FDEC(A6) which is at address 5B4FA0 (this will vary) - and in fact you can see the asterisk in the listing denoting that I have done just that. Now exit, enter your name and company and serial number (keep typing anything until the OK button lights up) and hit OK. Now TMON breaks in again at the breakpoint. Now we can begin the crack. Determining how to implement the crack. Before you continue, think about what the program must do at this point if it wants to validate your serial number (here it helps to have read Inside Mac on dialogs). First the program must obtain a pointer to the dialog item #5 (the serial number field) and then it must obtain a pointer to the text contained in that item. Knowing this, you can just scan down until you see a GetDItem trap followed closely by a GetIText trap. After this last trap, the program can do its validation. Here is that piece of code: MOVE.L A3,-(A7) _GetIText MOVE.L A3,-(A7) JSR ^$005B5670 TST.L D0 ADDQ.L #4,A7 BMI ^$005B50C8 CMPI.L #$00000005,D0 BGT ^$005B50C8 ADD.L D0,D0 MOVE.W ^$005B500A(D0.L),D0 JMP ^$005B5008(D0.W) We can note that A3 is the pointer that will point to the text after the trap. Once A3 has the text, a subroutine is called and D0 is tested. At this point, we cannot be sure whether the branch executes if the serial passed or failed, so we had better take a quick look at the code at address 5B50C8. I am not going to show it here, but that code does some crap then calles ParamText and then a Dialog call so it is probably safe to guess that the branch above jumps to the error code. With this assumption in mind, what can we do about it? An initial guess would be to just make that BMI either not execute or even better, make the BMI branch down to the ADD.L D0,D0. Unfortunately, if you look at the last two lines, you can see that D0 not only determines whether the code branches to the error routine, but is then used for a JMP instruction so we had better take care of D0. Let's take a quick look at that JSR up a few lines that sets D0 in the first place and remember, we are trying to figure out what D0 should be set to. Also remember that the branch is a BMI meaning that the error occurs if the high bit of D0 is set. 004B1508:'CODE'®$0003ƒ$04C8+$096C LINK.W A6,#$FF00 004B150C:'CODE'®$0003ƒ$04C8+$0970 MOVEM.L A3/A4,-(A7) 004B1510:'CODE'®$0003ƒ$04C8+$0974 LEA `FF00(A6),A4 004B1514:'CODE'®$0003ƒ$04C8+$0978 MOVEA.L $0008(A6),A3 004B1518:'CODE'®$0003ƒ$04C8+$097C MOVEQ #$00,D0 004B151A:'CODE'®$0003ƒ$04C8+$097E MOVE.B (A3),D0 004B151C:'CODE'®$0003ƒ$04C8+$0980 MOVEQ #$06,D1 004B151E:'CODE'®$0003ƒ$04C8+$0982 CMP.L D0,D1 004B1520:'CODE'®$0003ƒ$04C8+$0984 BLE.S ^$004B1526 ;'CODE'®$0003ƒ$04C8+$98A 004B1522:'CODE'®$0003ƒ$04C8+$0986 MOVEQ #`FF,D0 004B1524:'CODE'®$0003ƒ$04C8+$0988 BRA.S ^$004B1592 ;'CODE'®$0003ƒ$04C8+$9F6 004B1526:'CODE'®$0003ƒ$04C8+$098A MOVEQ #$00,D0 004B1528:'CODE'®$0003ƒ$04C8+$098C MOVE.B (A3),D0 004B152A:'CODE'®$0003ƒ$04C8+$098E MOVEQ #$28,D1 ;'(' 004B152C:'CODE'®$0003ƒ$04C8+$0990 CMP.L D0,D1 004B152E:'CODE'®$0003ƒ$04C8+$0992 BGE.S ^$004B1534 ;'CODE'®$0003ƒ$04C8+$998 004B1530:'CODE'®$0003ƒ$04C8+$0994 MOVEQ #`FF,D0 004B1532:'CODE'®$0003ƒ$04C8+$0996 BRA.S ^$004B1592 ;'CODE'®$0003ƒ$04C8+$9F6 004B1534:'CODE'®$0003ƒ$04C8+$0998 MOVE.L A4,-(A7) 004B1536:'CODE'®$0003ƒ$04C8+$099A PEA $3802 ;$000037D8+$2A 004B153A:'CODE'®$0003ƒ$04C8+$099E JSR $1702(A5) 004B153E:'CODE'®$0003ƒ$04C8+$09A2 MOVE.L A4,-(A7) 004B1540:'CODE'®$0003ƒ$04C8+$09A4 JSR $0532(A5) 004B1544:'CODE'®$0003ƒ$04C8+$09A8 MOVE.L A3,-(A7) 004B1546:'CODE'®$0003ƒ$04C8+$09AA MOVE.L A4,-(A7) 004B1548:'CODE'®$0003ƒ$04C8+$09AC JSR $0392(A5) 004B154C:'CODE'®$0003ƒ$04C8+$09B0 TST.L D0 004B154E:'CODE'®$0003ƒ$04C8+$09B2 LEA $0014(A7),A7 004B1552:'CODE'®$0003ƒ$04C8+$09B6 BEQ.S ^$004B1558 ;'CODE'®$0003ƒ$04C8+$9BC 004B1554:'CODE'®$0003ƒ$04C8+$09B8 MOVEQ #$05,D0 004B1556:'CODE'®$0003ƒ$04C8+$09BA BRA.S ^$004B1592 ;'CODE'®$0003ƒ$04C8+$9F6 004B1558:'CODE'®$0003ƒ$04C8+$09BC MOVE.B $0001(A3),D0 004B155C:'CODE'®$0003ƒ$04C8+$09C0 SUBI.B #$30,D0 004B1560:'CODE'®$0003ƒ$04C8+$09C4 BCS.S ^$004B1590 ;'CODE'®$0003ƒ$04C8+$9F4 004B1562:'CODE'®$0003ƒ$04C8+$09C6 CMPI.B #$02,D0 004B1566:'CODE'®$0003ƒ$04C8+$09CA BHI.S ^$004B1590 ;'CODE'®$0003ƒ$04C8+$9F4 004B1568:'CODE'®$0003ƒ$04C8+$09CC MOVEQ #$00,D1 004B156A:'CODE'®$0003ƒ$04C8+$09CE MOVE.B D0,D1 004B156C:'CODE'®$0003ƒ$04C8+$09D0 ADD.W D1,D1 004B156E:'CODE'®$0003ƒ$04C8+$09D2 MOVE.W ^$004B1576(D1.W),D1 ;'CODE'®$0003ƒ$04C8+$9DA 004B1572:'CODE'®$0003ƒ$04C8+$09D6 JMP ^$004B1574(D1.W) ;'CODE'®$0003ƒ$04C8+$9D8 There are no traps here to quickly tell us what is happening, but we can quickly look at the lines that affect D0. Basically, there are a bunch of interspersed MOVEQ instructions putting various values into D0. One of the values is $FF which (since the high bit of $FF is set - in fact, all the bits of $FF are set) must trigger the error in the previous procedure. Other values include 5 and 0. Right now, that is enough information to proceed with the previous procedure - if we need more in depth info, we can always come back. So we have the following code again: MOVE.L A3,-(A7) JSR ^$005B5670 TST.L D0 ADDQ.L #4,A7 BMI ^$005B50C8 CMPI.L #$00000005,D0 BGT ^$005B50C8 ADD.L D0,D0 MOVE.W ^$005B500A(D0.L),D0 JMP ^$005B5008(D0.W) Once again, we have an initial BMI which tells us that $FF won't work for D0. We also have BGT after comparing D0 with 5 which branches to the error - so D0 must be between 0 and 5 (the other values we noted from the subroutine above). At this point, I would (and did) simply try inserting values into D0. I started with 5 and the program went into Demo mode - strike one. Next I tried 1 and some other error occured. Finally, I tried 0 and the program continued flawlessly. So you are asking, how exactly might you go about inserting these values into D0? Consider: once D0 is set to the proper value, the two branches become meaningless since they would not execute anyways (they only execute if there is an error). This little tidbit tells us that we can safely overwrite these instructions with anything we like. So we have several free bytes to put our own code into (don't panic yet - this is pretty straightforward) and all our code has to do is set D0 to 0 then proceed. One quick note: Never Never Ever modify code that affects the stack. If you do, you can easily cause system errors later on down the road. In the above code, this translates into not changing the ADDQ.L #4,A7 (A7 is the stack pointer, remember?). So what is the easiest way to put 0 into D0? Use a MOVEQ instruction. This is particularly nice because you probably do not know the machine hex code for instructions (like me). But that subroutine we looked at before is chalk full of MOVEQ instructions. If you look, a MOVEQ 0 #0,D0 translates into 70 00. So far so good except that the stupid BMI is one of those 4 byte branches. So we still have two bytes left that will be garbage since we just changed the first two. This is an excellent candidate for a NOP instruction - a two byte instruction that does absolutely nothing. The code for this (from the Cracker's Guide Part 1) is 4E 71. So, open a dump window to the PC and find the BMI (I think it is 68 00 00 D4 or something like that). Change the four values to 70 00 4E 71 and now the program loads D0 with the correct value and proceeds as if nothing had happened. Now you have the crack, but you want to make a cracked / un-serialized copy right? So, unstuff a fresh copy of the application, open it in Resedit, and open the proper CODE resource. To find the ID #, look back at the TMON listing. It says CODE 0003 plus some benutia about the File reference number and then +nnnn where nnnn is the offset from the beginning of the Code resource. There is all you need. Open CODE ID 3 and jump down to line 2E8 (since 2EE is our byte) and change the 68 00 00 D4 to 70 00 4E 71. Now run it and enter anything you like for the serial number. QuickFormat 7.01 [due to burn-out, the final sections have not been written up] 33E: QUAL CHECKFOR ; b# =508 s#3 =proc196 ;-refs - 3/INITPROG 33E: 4E56 FFE4 'NV..' CHECKFOR LINK A6,#-$1C 342: 48E7 0108 'H...' MOVEM.L D7/A4,-(A7) 346: 594F 'YO' SUBQ #4,A7 348: 2F3C 6465 6D6F '/